package com.library.books.service.impl;

import java.sql.Wrapper;
import java.util.List;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.library.books.domain.Print;
import com.library.books.domain.PrintRecord;
import com.library.books.domain.vo.print.PrintRequireInfoData;
import com.library.books.domain.vo.print.PrintTimestampGroupRecordVo;
import com.library.books.mapper.PrintMapper;
import com.library.books.service.IPrintRecordService;
import com.library.books.service.IPrintService;
import com.library.common.enums.PrintStatus;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 打印Service业务层处理
 *
 * @author hb
 * @date 2024-12-09
 */
@Service
public class PrintServiceImpl extends ServiceImpl<PrintMapper, Print> implements IPrintService
{

    @Resource
    IPrintRecordService printRecordService;

    /**
     * 查询打印列表
     *
     *
     * @param print 打印
     * @return 打印
     */
    @Override
    public List<Print> selectPrintList(Print print) {
        return baseMapper.selectPrintList(print);
    }

    /**
     * 查询书籍拼接书籍副本拼接书籍规则拼接书籍书架拼接打印拼接打印记录列表
     *  - 打印信息列表（查询打印所需信息列表）
     *  - 书籍信息（必须返回）
     *  - 书籍副本（必须返回）
     *  - 书籍规则（）
     *  - 书籍存放书架（）
     *  - 书籍副本打印（部分返回）
     *  - 书籍副本打印记录（部分返回）
     * @param join 参数
     * @return 打印所需数据列表
     */
    @Override
    public List<PrintRequireInfoData> selectPrintRequireInfoDataList(PrintRequireInfoData join) {
        return baseMapper.selectPrintRequireInfoDataList(join);
    }

    /**
     * 打印提交（确认已打印）
     * @param printRequireInfoDataList 打印所需数据
     * @return 是否处理完成
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean printSubmit(String status , List<PrintRequireInfoData> printRequireInfoDataList) {
        // 存在重复打印
        update(Wrappers.lambdaUpdate(Print.class)
            .set(Print::getPrintStatus,status)
            .in(Print::getPrintId,printRequireInfoDataList.stream().map(PrintRequireInfoData::getPrintId).distinct().collect(Collectors.toList()))
        );
        long time = System.currentTimeMillis();
        List<PrintRecord> printRecordList = printRequireInfoDataList.stream().map(b -> {
            PrintRecord printRecord = new PrintRecord();
            BeanUtils.copyProperties(b, printRecord);
            printRecord.setTimestamp(time);
            printRecord.setPrintStatus(status);
            printRecord.setPrintRecordId(null);
            return printRecord;
        }).collect(Collectors.toList());
        return printRecordService.saveBatch(printRecordList);
    }

    /**
     * 打印取消（删除打印数据）
     * @param group 取消的打印分组记录
     * @return 是否处理完成
     */
    @Override
    public boolean printCancel(PrintTimestampGroupRecordVo group) {
        // 存在重复打印
        update(Wrappers.lambdaUpdate(Print.class)
            .set(Print::getPrintStatus,PrintStatus.NO.getCode())
            .in(Print::getPrintId,group.getPrintIds())
            .eq(Print::getPrintStatus,PrintStatus.WAIT.getCode())
        );
        // 删除掉指定记录id分组记录数据
        return printRecordService.remove(Wrappers.lambdaQuery(PrintRecord.class)
            .eq(PrintRecord::getTimestamp,group.getPrintTimestamp())
            .in(PrintRecord::getPrintId,group.getPrintIds())
        );
    }

    /**
     * 打印确认（更新已打印）
     * @param group 取消的打印分组记录
     * @return 是否处理完成
     */
    @Override
    public boolean printAck(PrintTimestampGroupRecordVo group) {
        // 存在重复打印
        update(Wrappers.lambdaUpdate(Print.class)
            .set(Print::getPrintStatus,PrintStatus.SUC.getCode())
            .in(Print::getPrintId,group.getPrintIds())
            .eq(Print::getPrintStatus,PrintStatus.WAIT.getCode())
        );
        // 更新指定记录id分组记录数据
        return printRecordService.update(Wrappers.lambdaUpdate(PrintRecord.class)
            .set(PrintRecord::getPrintStatus,PrintStatus.SUC.getCode())
            .in(PrintRecord::getPrintId,group.getPrintIds())
            .eq(PrintRecord::getTimestamp,group.getPrintTimestamp())
        );
    }

    /** 未打印数量
     * @param status 打印状态枚举
     * @return 数量
     */
    @Override
    public Long selectPrintCount(PrintStatus status) {
        return baseMapper.selectPrintCount(status.getCode());
    }

}
